<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Demo</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <style>
    body {
      font-family: Arial, sans-serif;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #f8f9fa
    }

    .container {
      width: 600px;
      background: #fff;
      border-radius: 5px;
      padding: 40px 20px
    }

    .modal-steps {
      display: flex;
      justify-content: space-between;
      position: relative;
      margin-bottom: 20px
    }
    .modal-steps::after{
        content: "";
        position: absolute;
        top: 20%;
        left: 70px;
        right: 0;
        width: 450px;
        height: 2px;
        background-color: #eaeaea;
        z-index: -1
    }

    .step {
      text-align: center;
      position: relative;
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 10px
    }

    .dot {
      height: 20px;
      width: 20px;
      border-radius: 50%;
      background-color: #eaeaea;
      display: inline-block;
      margin: 0 auto;
      position: relative;
      z-index: 1
    }

    .label {
      font-size: 14px;
      color: #6c757d
    }

    .completed .dot {
      background-color: #39c0ba
    }

    .current .dot {
      border: 2px solid #39c0ba
    }

    .step-line {
      position: absolute;
      top: 10px;
      left: 70px;
      right: 0;
      height: 2px;
      background-color: #39c0ba;
      z-index: 0;
      transition: width .4s ease
    }

    .step-line.completed {
      background-color: #39c0ba
    }

    .step-slide {
      display: none;
      text-align: center;
      font-weight: 700
    }

    .step-main {
      position: relative;
      margin-bottom: 20px
    }

    .step-controlbar {
      display: flex;
      justify-content: space-between
    }

    .unVisible {
      opacity: 0;
      pointer-events: none
    }

    button {
      padding: 10px 20px;
      background-color: #007bff;
      color: #fff;
      border: none;
      border-radius: 5px;
      cursor: pointer
    }

    button:disabled {
      background-color: #6c757d
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="modal-steps">
      <div class="step">
        <div class="dot"></div><label class="label">第一步</label>
      </div>
      <div class="step">
        <div class="dot"></div><label class="label">第二步</label>
      </div>
      <div class="step">
        <div class="dot"></div><label class="label">第三步</label>
      </div>
      <div class="step">
        <div class="dot"></div><label class="label">第四步</label>
      </div>
      <div class="step-line" id="line"></div>
    </div>
    <div class="step-main">
      <div class="step-slide">内容1</div>
      <div class="step-slide">内容2</div>
      <div class="step-slide">内容3</div>
      <div class="step-slide">内容4</div>
    </div>
    <div class="step-controlbar"><button type="button" class="unVisible" id="pre">上一步</button> <button type="button"
        id="next">下一步</button></div>
  </div>
  <script> 
    let current = 0; 
    // 获取所有的步骤元素  
    const steps = document.querySelectorAll('.step');  
    // 获取所有的幻灯片（步骤内容）元素  
    const slides = document.querySelectorAll('.step-slide');   
    // 获取“上一步”按钮  
    const preBtn = document.getElementById('pre');  
    // 获取“下一步”按钮  
    const nextBtn = document.getElementById('next');  
    // 获取表示当前步骤进度的线条元素  
    const line = document.getElementById('line');  
    // 更新步骤显示状态的函数  
    function updateStepDisplay() {  
      // 遍历所有幻灯片，根据当前步骤索引显示或隐藏幻灯片  
      slides.forEach((slide, index) => {  
        slide.style.display = (index === current) ? 'block' : 'none';  
      });  
      // 遍历所有步骤，根据当前步骤索引添加或移除“已完成”和“当前”类  
      steps.forEach((step, index) => {  
        if (index < current) {  
          step.classList.add('completed'); // 如果步骤索引小于当前索引，则标记为已完成  
        } else {  
          step.classList.remove('completed'); // 否则，移除“已完成”类  
        }  
    
        if (index === current) {  
          step.classList.add('current'); // 如果步骤索引等于当前索引，则标记为当前步骤  
        } else {  
          step.classList.remove('current'); // 否则，移除“当前”类  
        }  
      });  
    
      // 根据当前步骤索引更新进度线条的宽度  
      // 注意：这里的计算方式是为了让线条在最后一个步骤之前不完全填满，可能是为了视觉效果  
      line.style.width = (current / (steps.length - 1)) * 75 + '%';  
        
      // 如果当前是最后一个步骤，则给线条添加“已完成”类  
      line.classList.toggle('completed', current === steps.length - 1);  
        
      // 如果当前是第一个步骤，则隐藏“上一步”按钮  
      preBtn.classList.toggle('unVisible', current === 0);  
        
      // 如果当前是最后一个步骤，则“下一步”按钮的文本变为“完成”，否则保持为“下一步”  
      nextBtn.innerHTML = (current === slides.length - 1) ? '完成' : '下一步';  
    }  
    
    // 为“下一步”按钮添加点击事件监听器  
    nextBtn.addEventListener('click', function () {  
      if (current < slides.length - 1) { // 如果当前不是最后一个步骤  
        current++;   
        updateStepDisplay(); // 更新步骤显示状态  
      }  
    });  
    
    // 为“上一步”按钮添加点击事件监听器  
    preBtn.addEventListener('click', function () {  
      if (current > 0) { // 如果当前不是第一个步骤  
        current--;  
        updateStepDisplay(); // 更新步骤显示状态  
      }  
    });  
      
    // 初始化步骤显示状态  
    updateStepDisplay();  
  </script>
</body>

</html>